﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.EisPack
{
    /// <summary>
    /// Accumulates the stabilized elementary similarity transformations used in the reduction of a 
    /// real general matrix to upper hessenberg form by elmhes.
    /// </summary>
    [Serializable]
    public static class EltranClass
    {
        /// <summary>
        /// Accumulates the stabilized elementary similarity transformations used in the reduction of a 
        /// real general matrix to upper hessenberg form by elmhes.
        /// </summary>
        /// <param name="n">The n.</param>
        /// <param name="lo">The lo parameter.</param>
        /// <param name="hi">The hi parameter.</param>
        /// <param name="a">Contains the multipliers which were used in the reduction by 
        /// elmhes in its lower triangle below the subdiagonal.</param>
        /// <param name="intch">Contains information on the rows and columns interchanged in the reduction by 
        /// elmhes.</param>
        /// <param name="z">Contains the transformation matrix produced in the reduction by elmhes.</param>
        public static void Eltran(int n, int lo, int hi, double[,] a, int[] intch, double[,] z)
        {
            /* This routine is a translation of the Algol procedure from
             * Handbook for Automatic Computation, vol. II, Linear Algebra,
             * by Wilkinson and Reinsch, Springer-Verlag.
             */
            int i, j, kl, mm, mp, mp1;

            /* Initialize z to identity matrix. */
            for (j = 0; j < n; j++)
            {
                for (i = 0; i < n; i++)
                {
                    z[i, j] = 0.0;
                }
                z[j, j] = 1.0;
            }
            kl = hi - lo - 1;
            if (kl < 1)
            {
                goto _200;
            }
            for (mm = 1; mm <= kl; mm++)
            {
                mp = hi - mm;
                mp1 = mp + 1;
                for (i = mp1; i <= hi; i++)
                {
                    z[i, mp] = a[i, mp - 1];
                }
                i = intch[mp];
                if (i == mp)
                {
                    goto _140;
                }
                for (j = mp; j <= hi; j++)
                {
                    z[mp, j] = z[i, j];
                    z[i, j] = 0.0;
                }
                z[i, mp] = 1.0;
                _140:
                ;
            }
            _200:
            ;
        }
    }
}